package edu.csl.study.springboot.zookeeper.service;

import lombok.extern.log4j.Log4j2;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
@Log4j2
public class CuratorService {

    @Autowired
    private CuratorFramework client;
    //ZooKeeper分布式锁的实现原理是由ZNode节点的创建与删除跟监听机制构成的
    //而ZNoe节点将对应一个具体的路径-跟Unix文件夹路径类似，需要以 / 开头
    @Value("${curator.namespace}")
    private String namespace;
    private static final String pathPrefix="/zkLock/";
    /**
     * 处理用户提交注册的请求-加ZooKeeper分布式锁
     */
    public InterProcessMutex getlock(String key) {
        //创建ZooKeeper互斥锁组件实例，需要将监控用的客户端实例、精心构造的共享资源作为构造参数
        return new InterProcessMutex(client,"/"+namespace + pathPrefix+key);
    }
    /**
     * 一直阻塞，直到可以使用才停止。
     * @param lock
     */
    public void lock(InterProcessMutex lock)   {
        try{
             lock.acquire();
        }catch(Exception e){
            log.error("获取ZooKeeper分布式锁出现异常：{}",e.getMessage(),e);
            throw new RuntimeException("获取ZooKeeper分布式锁出现异常："+e.getMessage(),e);
        }
    }

    /**
     * 阻塞
     * @param lock
     * @param expireSeconds
     * @return
     */
    public boolean lock(InterProcessMutex lock,long expireSeconds)   {
        try{
            return lock.acquire(expireSeconds, TimeUnit.SECONDS);
        }catch(Exception e){
            log.error("获取ZooKeeper分布式锁出现异常：{}",e.getMessage(),e);
            throw new RuntimeException("获取ZooKeeper分布式锁出现异常："+e.getMessage(),e);
        }
    }
    public void unLock(InterProcessMutex lock ){
        try{
            lock.release();
        }catch (Exception e){
            log.error("释放分布式锁出现异常（忽略异常）：{}",e.getMessage());
        }

    }


}
